package com.example.gateway.route.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

@Component
public class CustomFilterGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomFilterGatewayFilterFactory.Config> {

    public CustomFilterGatewayFilterFactory(){
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println(config);
                ServerHttpRequest request = exchange.getRequest();
                ServerHttpResponse response = exchange.getResponse();
                if(request.getQueryParams().get("filter")==null){
                    //放行
                    System.out.println("放行");
                    return chain.filter(exchange);
                }
                //进行过滤
                System.out.println("过滤处理");
//                Mono<ServerResponse> filterResponse = ServerResponse.status(HttpStatus.NOT_ACCEPTABLE)
//                        .contentType(MediaType.APPLICATION_JSON)
//                        //设置响应体
//                        .body(BodyInserters.fromValue("已经被过滤处理"));

                //设置响应的内容
                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                //设置响应码为不接受该请求
                response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                //将响应体修改为过滤的的响应结果
                return response.writeWith(Mono.fromSupplier(()->{
                    DataBufferFactory bufferFactory = response.bufferFactory();
                    try {
                        HashMap<String, Object> responseData = new HashMap<>();
                        responseData.put("code", HttpStatus.NOT_ACCEPTABLE);
                        responseData.put("data","被过滤处理掉了");
                        return bufferFactory.wrap(new ObjectMapper().writeValueAsBytes(responseData));
                    }
                    catch (JsonProcessingException e) {
                        System.out.println("CustomFilterGatewayFilterFactory出错");
                        return bufferFactory.wrap(new byte[0]);
                    }
                }));
            }
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name","regexp");
    }

    @Validated
    public static class Config {
        @NotEmpty
        private String name;
        private String regexp;
        public Config(){
        }
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getRegexp() {
            return regexp;
        }

        public void setRegexp(String regexp) {
            this.regexp = regexp;
        }

        @Override
        public String toString() {
            return "Config{" +
                    "name='" + name + '\'' +
                    ", regexp='" + regexp + '\'' +
                    '}';
        }
    }
}
